//    Copyright (C) Clear Office.  All rights reserved.
using System.Collections.Generic;
using Office.Core.Serialization;
using Office.Spreadsheet.Serialization;

namespace Office.Spreadsheet.PivotTable
{
    internal class PivotCacheDefinition : IOfficeXmlSerializable
    {
        private bool _backgroundQuery;
        private List<CacheField> _cacheFields;

        private List<CacheHierarchy> _cacheHierarchies;
        private CacheSource _cacheSource;

        private List<CalculatedItem> _calculatedItems;

        private List<CalculatedMember> _calculatedMembers;
        private byte _createdVersion;

        private List<Dimension> _dimensions;
        private bool _enableRefresh;

        private ExtensionElement _extLst;
        private bool _invalid;
        private List<PCDKPI> _kpis = new List<PCDKPI>();
        private List<MeasureDimensionMap> _maps;
        private List<MeasureGroup> _measureGroups;
        private byte _minRefreshableVersion;
        private uint? _missingItemsLimit;
        private bool _optimizeMemory;
        private uint? _recordCount;
        private string _refreshedBy;
        private double? _refreshedDate;
        private byte _refreshedVersion;
        private bool _refreshOnLoad;
        private bool _saveData;
        private bool _supportAdvancedDrill;
        private bool _supportSubquery;
        private TupleCache _tupleCache;
        private bool _tupleCacheBoolean;
        private bool _upgradeOnRefresh;
        private PivotCacheRecords _PivotCacheRecords;

        public CacheSource cacheSource
        {
            get { return _cacheSource; }
        }

        public List<CacheField> CacheFields
        {
            get { return _cacheFields; }
        }

        public List<CacheHierarchy> CacheHierarchies
        {
            get { return _cacheHierarchies; }
        }

        public List<PCDKPI> kpis
        {
            get { return _kpis; }
            set { _kpis = value; }
        }

        public TupleCache TupleCache
        {
            get { return _tupleCache; }
            set { _tupleCache = value; }
        }

        public List<CalculatedItem> CalculatedItems
        {
            get { return _calculatedItems; }
        }

        public List<CalculatedMember> CalculatedMembers
        {
            get { return _calculatedMembers; }
        }

        public List<Dimension> Dimensions
        {
            get { return _dimensions; }
        }

        public List<MeasureGroup> MeasureGroups
        {
            get { return _measureGroups; }
        }

        public List<MeasureDimensionMap> Maps
        {
            get { return _maps; }
        }

        public ExtensionElement Extension
        {
            get { return _extLst; }
            set { _extLst = value; }
        }

        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            using (ReadContext c = context.Read("pivotCacheDefinition"))
            {
                string rid = c.GetOptionalString(OfficeConstants.RelationshipNamespace + "id");
                if (rid != null)
                {
                    using (var c2 = c.OpenRelatedContext(rid, c.NamespaceUri))
                    {
                        this._PivotCacheRecords = c2.ReadElement<PivotCacheRecords>();
                    }
                }
                _invalid = c.GetOptionalBoolean("invalid", false);
                _saveData = c.GetOptionalBoolean("saveData", true);
                _refreshOnLoad = c.GetOptionalBoolean("refreshOnLoad", false);
                _optimizeMemory = c.GetOptionalBoolean("optimizeMemory", false);
                _enableRefresh = c.GetOptionalBoolean("enableRefresh", true);
                _refreshedBy = c.GetOptionalString("refreshBy");
                _refreshedDate = c.GetOptionalDouble("refreshDate");
                _backgroundQuery = c.GetOptionalBoolean("backgroundQuery", false);
                _missingItemsLimit = c.GetOptionalUInteger("missingItemsLimit");
                _createdVersion = (byte) c.GetOptionalInteger("createdVersion", 0);
                _refreshedVersion = (byte) c.GetOptionalInteger("refreshedVersion", 0);
                _minRefreshableVersion = (byte) c.GetOptionalInteger("minRefreshableVersion", 0);
                _recordCount = c.GetOptionalUInteger("recordCount");
                _upgradeOnRefresh = c.GetOptionalBoolean("upgradeOnRefresh", false);
                _tupleCacheBoolean = c.GetOptionalBoolean("tupleCache", false);
                _supportSubquery = c.GetOptionalBoolean("supportSubquery", false);
                _supportAdvancedDrill = c.GetOptionalBoolean("supportAdvancedDrill", false);

                _cacheSource = c.ReadElement<CacheSource>();
                _cacheFields = c.ReadOptionalListElement<CacheField>("cacheFields", "cacheField");
                _cacheHierarchies = c.ReadOptionalListElement<CacheHierarchy>("cacheHierarchies", "cacheHierarchy");
                _kpis.Clear();
                _kpis.AddRange(c.ReadOptionalListElement<PCDKPI>("kpis", "kpi"));
                _tupleCache = c.ReadOptionalElement<TupleCache>("tupleCache");
                _calculatedItems = c.ReadOptionalListElement<CalculatedItem>("calculatedItems", "calculatedItem");
                _calculatedMembers = c.ReadOptionalListElement<CalculatedMember>("calculatedMembers", "calculatedMember");
                _dimensions = c.ReadOptionalListElement<Dimension>("dimensions", "dimension");
                _measureGroups = c.ReadOptionalListElement<MeasureGroup>("measureGroups", "measureGroup");
                _maps = c.ReadOptionalListElement<MeasureDimensionMap>("maps", "map");
                _extLst = c.ReadOptionalElement<ExtensionElement>("extLst");
            }
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            using (WriteContext c = context.Write("pivotCacheDefinition"))
            {
                if (_PivotCacheRecords != null)
                {
                    using (var c2 = c.CreateRelatedContext(c.Prefix, c.NamespaceUri, c.GetAvailableUri("/xl/pivotCache/pivotCacheRecords{0}.xml"),
                        SpreadsheetConstants.PivotCacheRecordsRelationship, SpreadsheetConstants.PivotCacheRecordsContentType))
                    {
                        c2.WriteElement(_PivotCacheRecords);
                        c.SetString(OfficeConstants.RelationshipNamespace + "id", c2.Relationship.Id);
                    }
                }
                c.SetOptionalBoolean("invalid", _invalid, false);
                c.SetOptionalBoolean("saveData", _saveData, true);
                c.SetOptionalBoolean("refreshOnLoad", _refreshOnLoad, false);
                c.SetOptionalBoolean("optimizeMemory", _optimizeMemory, false);
                c.SetOptionalBoolean("enableRefresh", _enableRefresh, true);
                c.SetOptionalString("refreshBy", _refreshedBy);
                c.SetOptionalDouble("refreshedDate", _refreshedDate);
                c.SetOptionalBoolean("backgroundQuery", _backgroundQuery, false);
                c.SetOptionalUInteger("missingItemsLimit", _missingItemsLimit);
                c.SetOptionalInteger("createdVersion", _createdVersion, 0);
                c.SetOptionalInteger("refreshedVersion", _refreshedVersion, 0);
                c.SetOptionalInteger("minRefreshableVersion", _minRefreshableVersion, 0);
                c.SetOptionalUInteger("recordCount", _recordCount);
                c.SetOptionalBoolean("upgradeOnRefresh", _upgradeOnRefresh, false);
                c.SetOptionalBoolean("tupleCache", _tupleCacheBoolean, false);
                c.SetOptionalBoolean("supportSubquery", _supportSubquery, false);
                c.SetOptionalBoolean("supportAdvancedDrill", _supportAdvancedDrill, false);

                c.WriteElement(_cacheSource);
                WriteItems(c, "cacheFields", _cacheFields);
                WriteItems(c, "cacheHierarchies", _cacheHierarchies);
                WriteItems(c, "kpis", _kpis);
                c.WriteOptionalElement(_tupleCache);
                WriteItems(c, "calculatedItems", _calculatedItems);
                WriteItems(c, "calculatedMembers", _calculatedMembers);
                WriteItems(c, "dimensions", _dimensions);
                WriteItems(c, "measureGroups", _measureGroups);
                WriteItems(c, "maps", _maps);
                c.WriteOptionalElement(_extLst);
            }
        }

        #endregion

        private void WriteItems<T>(WriteContext context, string names, ICollection<T> elements)
            where T : IOfficeXmlSerializable
        {
            if (elements == null || elements.Count == 0)
                return;
            using (WriteContext c2 = context.Write(names))
            {
                c2.SetInteger("count", elements.Count);
                c2.WriteElements(elements);
            }
        }
    }
}